package xyz.xmh.dao.file;

import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import xyz.xmh.pojo.enums.CategoryEnum;
import xyz.xmh.pojo.enums.CheckNameEnum;
import xyz.xmh.pojo.request.file.ListRequest;
import xyz.xmh.pojo.request.file.MultiDownloadUrlRequest;
import xyz.xmh.pojo.request.file.SearchRequest;
import xyz.xmh.pojo.request.file.UpdateRequest;
import xyz.xmh.pojo.response.file.CreateFileResponse;

import java.nio.file.Path;


/**
 * 反应式文件接口
 *
 * @author xuMingHai
 */
public interface ReactiveFileDao {

    /**
     * 默认参数请求的文件列表获取
     *
     * @return 指定交换后响应操作的合同。
     */
    WebClient.ResponseSpec list();

    /**
     * 自定义请求参数的文件列表获取
     *
     * @param listRequest 文件请求参数
     * @return 指定交换后响应操作的合同。
     */
    WebClient.ResponseSpec list(ListRequest listRequest);

    /**
     * 根据文件名搜索文件
     *
     * @param fileName 文件名
     * @return 指定交换后响应操作的合同。
     */
    WebClient.ResponseSpec search(String fileName);


    /**
     * 根据指定的文件名和文件类型搜索文件
     *
     * @param fileName     文件名
     * @param categoryEnum 文件类型
     * @return 指定交换后响应操作的合同。
     */
    WebClient.ResponseSpec search(String fileName, CategoryEnum categoryEnum);


    /**
     * 根据指定的文件名和文件类型搜索文件
     *
     * @param searchRequest 自定义搜索请求参数
     * @return 指定交换后响应操作的合同。
     */
    WebClient.ResponseSpec search(SearchRequest searchRequest);

    /**
     * 获取指定文件的信息
     *
     * @param fileId 文件ID
     * @return 响应操作
     */
    WebClient.ResponseSpec get(String fileId);

    /**
     * 获取文件的下载地址信息
     *
     * @param fileId 文件ID
     * @return 响应操作
     */
    WebClient.ResponseSpec getDownloadUrl(String fileId);

    /**
     * 下载文件，支持分段下载，断点续传
     *
     * @param fileId      文件ID
     * @param httpHeaders 表示 HTTP 请求头
     * @return 响应实体
     */
    Mono<ResponseEntity<Resource>> downloadFile(String fileId, HttpHeaders httpHeaders);

    /**
     * 获取多个文件的下载url
     *
     * @param multiDownloadUrlRequest 多文件下载请求
     * @return url
     */
    WebClient.ResponseSpec getMultiDownloadUrl(MultiDownloadUrlRequest multiDownloadUrlRequest);

    /**
     * 下载多个文件，支持分段下载，断点续传
     *
     * @param multiDownloadUrlRequest 多个文件请求
     * @param httpHeaders             http请求头
     * @return 响应实体
     */
    Mono<ResponseEntity<Resource>> multiDownloadFile(MultiDownloadUrlRequest multiDownloadUrlRequest, HttpHeaders httpHeaders);

    /**
     * 创建文件夹
     *
     * @param parentFileId  父目录ID
     * @param name          文件夹名
     * @param checkNameEnum 同名策略
     * @return 响应后续操作
     */
    WebClient.ResponseSpec createFolder(String parentFileId, String name, CheckNameEnum checkNameEnum);

    /**
     * 创建文件夹，使用默认的同名策略，自动重命名
     *
     * @param parentFileId 父目录ID
     * @param name         文件夹名
     * @return 响应后续操作
     */
    WebClient.ResponseSpec createFolder(String parentFileId, String name);


    /**
     * 创建文件夹，使用默认的同名策略，自动重命名，使用默认的顶级目录
     *
     * @param name 文件夹名
     * @return 响应后续操作
     */
    WebClient.ResponseSpec createFolder(String name);

    /**
     * 上传文件（支持快传和零拷贝）
     *
     * @param parentFileId  父目录ID
     * @param path          文件路径
     * @param checkNameEnum 同名策略
     * @return 响应后的操作
     */
    Mono<CreateFileResponse> uploadFile(String parentFileId, Path path, CheckNameEnum checkNameEnum);

    /**
     * 上传文件，使用默认的同名策略，自动重命名（支持快传和零拷贝）
     *
     * @param parentFileId 父目录ID
     * @param path         文件路径
     * @return 响应后的操作
     */
    Mono<CreateFileResponse> uploadFile(String parentFileId, Path path);


    /**
     * 上传文件，使用默认的顶级目录、同名策略，自动重命名（支持快传和零拷贝）
     *
     * @param path 文件路径
     * @return 响应后的操作
     */
    Mono<CreateFileResponse> uploadFile(Path path);

    /**
     * 修改文件名
     * @param updateRequest 修改文件名的请求参数
     * @return 响应后续操作
     */
    WebClient.ResponseSpec update(UpdateRequest updateRequest);

    /**
     * 修改文件名
     * @param fileId 文件ID
     * @param name 修改成的文件名
     * @return 响应后续操作
     */
    WebClient.ResponseSpec update(String fileId, String name);


}

